<template>
	<div class="tags-controller" id="tags-controller">
		<el-tag
			closable
			:key="tag"
			@click="clickTag(tag)"
			@close="handleClose(tag)"
			v-for="tag in sortStringArr(tags)"
		>
			{{ tag }}
		</el-tag>
		<el-input
			ref="InputRef"
			class="input-tag"
			v-model="inputTag"
			v-if="inputVisible"
			@blur="handleInputConfirm"
			@keyup.enter="handleInputConfirm"
		/>
		<el-button v-else size="small" @click="showInput"> + 新增标签 </el-button>

		<el-popconfirm
			v-if="showDelete"
			cancelButtonText="取消"
			confirmButtonText="确定"
			@confirm="deleteItemByKey"
			title="确定彻底删除此数据吗？"
		>
			<template #reference>
				<el-button v-if="!inputVisible" type="danger" size="small">
					删除此项
				</el-button>
			</template>
		</el-popconfirm>
	</div>
</template>

<script lang="ts" setup>
import { useRouter } from "vue-router";
import type { ElInput } from "element-plus";
import { sortStringArr } from "@/utils/common";
import { mergeChangeTagMsg } from "@/utils/tag";
import { ref, computed, nextTick, defineProps, defineEmits } from "vue";

const props = defineProps({
	tags: {
		type: Array,
		required: true,
	},
	showDelete: {
		type: Boolean,
		default: true,
	},
});

const inputTag = ref("");
const router = useRouter();
const inputVisible = ref(false);
const tags = computed(() => props.tags as string[]);
const InputRef = ref<InstanceType<typeof ElInput>>();
const emit = defineEmits(["change", "click", "delete"]);

const handleClose = (tag: string) => {
	tags.value.splice(tags.value.indexOf(tag), 1);
	emit(
		"change",
		mergeChangeTagMsg({
			tag,
			type: "delete",
			tags: Object.values(tags.value),
		})
	);
};

const showInput = () => {
	inputVisible.value = true;
	nextTick(() => {
		if (InputRef.value?.input) {
			InputRef.value.input.focus();
		}
	});
};

const handleInputConfirm = () => {
	if (inputTag.value) {
		const value = inputTag.value;
		if (tags.value.includes(value)) {
			emit(
				"change",
				mergeChangeTagMsg({
					tag: value,
					type: "exist",
					tags: Object.values(tags.value),
				})
			);
		} else {
			tags.value.push(value);
			emit(
				"change",
				mergeChangeTagMsg({
					tag: value,
					type: "add",
					tags: Object.values(tags.value),
				})
			);
		}
	}
	inputVisible.value = false;
	inputTag.value = "";
};

function clickTag(tag: string) {
	emit("click", tag);
	router.push({ name: "tree", query: { tags: tag } });
}

function deleteItemByKey() {
	emit("delete");
}
</script>

<style lang="less">
.tags-controller {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	button,
	span.el-tag {
		margin: 5px;
	}

	div.el-input {
		width: 82.35px;
		height: 23.5px;
		input {
			width: 82.35px;
			height: 23.5px;
			padding: 5px 11px;
		}
	}
}
</style>
